/*
 * Copyright (c) 2010-2013 Ruben Chakhmakhchyan. All rights reserved.
 * 
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Eclipse Public License
 * Version 1.0 (the 'License'). You may not use this file except in
 * compliance with the License. Please obtain a copy of the License at
 * http://opensource.org/licenses/EPL-1.0 and read it before using this file.
 */

#include "dib.h"


void* Dib::GetBits( PBITMAPINFOHEADER pbih )
{
    unsigned int colors = 0;
    switch ( pbih->biBitCount )
    {
    case 8: colors = sizeof( RGBQUAD ) << 8; break;
    case 1: colors = sizeof( RGBQUAD ) << 1; break;
    }

    return ( void* ) ( ( char* ) pbih + sizeof( BITMAPINFOHEADER ) + colors );
}

uint_t Dib::GetStride( PBITMAPINFOHEADER pbih )
{
    return ( ( pbih->biWidth * pbih->biBitCount + 31 ) & ( ~31 ) ) >> 3;
}

void Dib::CheckDirection( BITMAPINFOHEADER* pBih )
{
    BITMAPINFOHEADER& bih = *pBih;

    if ( bih.biHeight < 0 )
    {
        unsigned int absHeight = ::abs( bih.biHeight );
        int bound = absHeight / 2;
        unsigned int stride = ( ( bih.biWidth * bih.biBitCount + 31 ) & ( ~31 ) ) >> 3;
        char* tmpscan = new char[ stride ];
        char* bits = ( char* ) GetBits( &bih );
        char* scan1 = NULL;
        char* scan2 = NULL;
        for ( int i = 0; i < bound; i++ )
        {
            scan1 = bits + i * stride;
            scan2 = bits + ( absHeight - i - 1 ) * stride;
            ::memcpy( tmpscan, scan1, stride );
            ::memcpy( scan1, scan2, stride );
            ::memcpy( scan2, tmpscan, stride );
        }
        delete[] tmpscan;
        bih.biHeight = absHeight;
    }
}

size_t Dib::GetStride( size_t width, size_t bitCount )
{
    return ( ( width * bitCount + 31 ) & ( ~31 ) ) >> 3;
}

size_t Dib::GetSize( size_t width, size_t height, size_t bitCount )
{
    unsigned int colors = 0;
    switch ( bitCount )
    {
    case 8: colors = sizeof( RGBQUAD ) << 8; break;
    case 1: colors = sizeof( RGBQUAD ) << 1; break;
    }

    uint_t stride = GetStride( width, bitCount );

    return sizeof( BITMAPINFOHEADER ) + colors + stride * height;
}
